/** 
 * 工具集
 */

/**
 * 在一个棋盘上, 遍历,回调遍历到的子
 * 回调函数的调用:fun(x,y,board[x][y]);
 */
export function callback_board(board,fun) {
  const length = board.length;
  for(let x = 0;x<length;++x)
  {
    for(let y=0;y<length;++y)
    {
      fun(x,y,board[x][y]);
    }
  }
}


export function isAvalablePos(posX,posY,totalLength)
{
  if(totalLength<=posX || posX<0)
  {
    return false;
  }
  if(totalLength<=posY || posY<0)
  {
    return false;
  }
  return true;
}

/**
 * 取所有的对手落子
 * @return [[x,y],...]
 */
export function callback_opponent_pos(board_state,fun)
{
  var result_list=[];
  const length = board_state.length;
  callback_board(board_state,(x,y,value)=>{    
    if('O'==value)//var state = board_state[x][y];
    {
      fun(x,y,value);
      result_list.push([x,y]);
    }
    else
    {
    }
  });
  return result_list;
}

/**
 * 取一个点, 上下左右的情况
 * @callback x,y,value 
 */
export function callback_surround_dot_4(position,board_state,fun)
{
  const length = board_state.length;
  // ####    BEGIN internal function    ####
  let fun_cb_internal = (x,y)=>
  {
    if(isAvalablePos(x,y,length))
    {
      let value_in_pos = board_state[x][y];
      fun(x,y,value_in_pos);
    }
  };
  // ####    END  internal function    ####

      // 上:
      let position_up_x = position[0];
      let position_up_y = position[1]+1;// y是从下往上数的
      fun_cb_internal(position_up_x,position_up_y);
      // 下:
      let position_down_x = position[0];
      let position_down_y = position[1]-1;
      fun_cb_internal(position_down_x,position_down_y);
      // 左:
      let position_left_x = position[0]-1;
      let position_left_y = position[1];
      fun_cb_internal(position_left_x,position_left_y);
      // 右:
      let position_right_x = position[0]+1;
      let position_right_y = position[1];
      fun_cb_internal(position_right_x,position_right_y);
}

/**
 * 取链上所有的点
 * @param chains 棋盘上的链 游戏提供的分析数据
 * @param chain_number 链的序号
 * @return [] 坐标集 坐标示例:[0,0]
 */
export function get_all_position_of_chain(chains,chain_number)
{
  let result_list = [];
  callback_board(chains,(x,y,value)=>{
    if(value == chain_number)
    {
      result_list.push([x,y]);
    }
  });
  return result_list;
}

/**
 * 数组中是否有重复的坐标
 * @param arr []
 * @param pos [x,y]
 * @return true:有  false:没有
 */
export function is_pos_in_array(arr,pos)
{
  let included = false;

  for(let i=0;i<arr.length;++i)
  {
    if(pos[0] == arr[i][0] && pos[1] == arr[i][1])
    {
      included = true;
    }
  }
  return included;
}

/**
 * 一个链的所有出口
 * 我方的链或对方的链
 * @return [[x,y],...]
 */
export function all_exit_of_chain(chain_number,chains,board_state)
{
  // 取链上所有的点:
  let all_pos_of_chain = get_all_position_of_chain(chains,chain_number);
  // 存这个链的出口列表
  let arr_exit=[];
  // 遍历分析链上所有点:
  for(let pos_i =0;pos_i<all_pos_of_chain.length;++pos_i)
  {
    let pos = all_pos_of_chain[pos_i];
    callback_surround_dot_4(pos,board_state,(x,y,value)=>{
      if('.' == value)
      {
        let current_pos = [x,y];
        if(!is_pos_in_array(arr_exit,current_pos) )
        {
          arr_exit.push(current_pos);
        }
      }
    });
  }// END for pos_i
  // 结果,链有多少个出口:
  // GNS.print("####    38:",arr_exit);

  return arr_exit;
}